package com.dxy.yzs.marathon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dxy.yzs.marathon.domain.Label;
import com.dxy.yzs.marathon.domain.Post;
import com.dxy.yzs.marathon.domain.PostLabelRelation;
import com.dxy.yzs.marathon.domain.Reply;
import com.dxy.yzs.marathon.mapper.LabelMapper;
import com.dxy.yzs.marathon.mapper.PostLabelRelationMapper;
import com.dxy.yzs.marathon.mapper.PostMapper;
import com.dxy.yzs.marathon.mapper.ReplyMapper;
import com.dxy.yzs.marathon.param.PostProblemParam;
import com.dxy.yzs.marathon.service.PostService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements PostService{
    @Autowired
    private LabelMapper labelMapper;
    @Autowired
    private PostLabelRelationMapper postLabelRelationMapper;
    @Autowired
    private PostMapper postMapper;
    @Autowired
    private ReplyMapper replyMapper;

    /**
     * 创建问题
     * 问题 ---- 标签
     * @param postProblemParam
     */
    @Transactional
    @Override
    public Integer createPostProblem(PostProblemParam postProblemParam) {
//        1.创建问题
        Post post = new Post();
        post.setCreateTime(new Date());
        post.setAuthorId(postProblemParam.getUserId());
        post.setTitle(postProblemParam.getTitle());
        post.setReplyTimes(0);
        post.setUpdateTime(new Date());
        post.setAvatar(postProblemParam.getAvatar());
        postMapper.insert(post);
//        2.查询创建 标签
        List<Label> labels = postProblemParam.getLabels();
        for (Label label : labels) {
            Label exitsLabel = labelMapper.selectOne(
                    new QueryWrapper<Label>().eq("content", label.getContent())
            );
            if (exitsLabel == null) {
                Label newLabel = new Label();
                newLabel.setContent(label.getContent());
                newLabel.setType(label.getType());
                labelMapper.insert(newLabel);
                addLabelRelation(newLabel, post);
            } else {
                //        3.建立关联关系
                addLabelRelation(exitsLabel, post);
            }
        }

        return post.getId();
    }

    @Override
    public List<Post> search(String text) {
        return lambdaQuery().like(Post::getTitle, text).list();
    }

    @Override
    public List<Post> getCreateProblemsByUserId(Integer userId) {
        return postMapper.selectList(
                new QueryWrapper<Post>()
                        .eq("author_id", userId)
        );
    }

    private void addLabelRelation(Label label, Post post){
        PostLabelRelation labelRelation = new PostLabelRelation();
        labelRelation.setLabelId(label.getId());
        labelRelation.setPostId(post.getId());
        postLabelRelationMapper.insert(labelRelation);
    }

    @Override
    public Map<String, Object> detail(Integer postId) {
        Map<String, Object> result = new HashMap<>();

        // 获取贴子详情
        Map<String, Object> post = BeanUtil.beanToMap(postMapper.selectById(postId));
        // 获取发帖人名称
        String postUsername = postLabelRelationMapper.getPostUsername(postId);
        post.put("username", postUsername);
        result.put("post", post);

        // 获取标签
        LambdaQueryWrapper<PostLabelRelation> relationMapper = new LambdaQueryWrapper<>();
        relationMapper.eq(PostLabelRelation::getPostId, postId);

        List<PostLabelRelation> relations = postLabelRelationMapper.selectList(relationMapper);
        List<Integer> labelIds = relations.stream()
                .map(PostLabelRelation::getLabelId)
                .collect(Collectors.toList());

        if (CollectionUtil.isNotEmpty(labelIds)) {
            LambdaQueryWrapper<Label> labelWrapper = new LambdaQueryWrapper<>();
            labelWrapper.in(Label::getId, labelIds);

            List<Label> labels = labelMapper.selectList(labelWrapper);
            result.put("labels", labels);
        } else {
            result.put("labels", Collections.emptyList());
        }

        // 获取回答
        LambdaQueryWrapper<Reply> replyWrapper = new LambdaQueryWrapper<>();
        replyWrapper.eq(Reply::getType, 0)
                .eq(Reply::getTargetId, postId)
                .orderByDesc(Reply::getId);
        List<Reply> replies = replyMapper.selectList(replyWrapper);
        Map<Integer, Reply> replyMap = replies.stream().collect(Collectors.toMap(Reply::getId, Function.identity()));

        if (!replyMap.isEmpty()) {
            LambdaQueryWrapper<Reply> childReplyWrapper = new LambdaQueryWrapper<>();
            childReplyWrapper.in(Reply::getTargetId, replyMap.keySet());
            childReplyWrapper.eq(Reply::getType, 1);
            List<Reply> childReplies = replyMapper.selectList(childReplyWrapper);
            Map<Integer, List<Reply>> childReplyMap = childReplies.stream()
                    .collect(Collectors.groupingBy(Reply::getTargetId));

            List<Map<String, Object>> list = new ArrayList<>();
            for (Map.Entry<Integer, Reply> entry : replyMap.entrySet()) {
                Map<String, Object> map = BeanUtil.beanToMap(entry.getValue());
                List<Reply> replyList = childReplyMap.get(entry.getKey());
                map.put("childReplies", Objects.isNull(replyList) ? Collections.emptyList() : replyList);
                map.put("replyTimes", Objects.isNull(replyList) ? 0 : replyList.size());
                map.put("likeTimes", new Random().nextInt(10));
                list.add(map);
            }

            result.put("replies", list);
        } else {
            List<Map<String, Object>> list = replies.stream().map(reply -> {
                Map<String, Object> map = BeanUtil.beanToMap(reply);
                map.put("childReplies", Collections.emptyList());
                map.put("replyTimes", 0);
                map.put("likeTimes", new Random().nextInt(10));
                return map;
            }).collect(Collectors.toList());

            result.put("replies", list);
        }

        return result;
    }
}




